/*****************************************************************//**
 * \file   Macro.h
 * \brief  Macro
 * 
 * \author Wyatt
 * \date   March 2023
 *********************************************************************/
#ifndef _CODE_MACRO_H
#define _CODE_MACRO_H

#ifndef IN
#define IN
#endif // !IN

#ifndef OUT
#define OUT
#endif // !OUT

#define SAFE_DEL(x) if (x) { delete x; x = nullptr; }
#define SAFE_DEL_ARR(x) if (x) { delete [] x; x = nullptr; }

#define SHORT_TXT_MAX  (1024)

#define GET_NAME(x) #x
#define COMMAND(NAME)  { #NAME, NAME }

#if defined _M_X64 || defined _M_ARM || defined _M_ARM64
#define _UNALIGNED __unaligned
#else
#define _UNALIGNED
#endif

#ifdef __cplusplus
extern "C++"
{
	template <typename _CountofType, size_t _SizeOfArray>
	char(*__countof_helper(_UNALIGNED _CountofType(&_Array)[_SizeOfArray]))[_SizeOfArray];
#define ARR_COUNT(_Array) (sizeof(*__countof_helper(_Array)) + 0)
}
#else
#define ARR_COUNT(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#endif

#define C_PROP(classType, Var, ...)                                                                            \
	private: classType _##Var{##__VA_ARGS__};                                                                  \
	public:                                                                                                    \
	virtual void set##Var(const classType &V)  {_##Var = V; }                                                  \
	virtual classType get##Var() const {return _##Var; }

#define DECLARE_CLASS_TYPE_FUNC(class_type, str)                                                               \
template <typename T>                                                                                          \
static typename std::enable_if<std::is_same<T, class_type>::value, std::string>::type                          \
GetClassTypeStr(T& t) { return str; }                                                                          \
template <typename T>                                                                                          \
static typename std::enable_if<std::is_same<T, class_type>::value, std::string>::type                          \
GetClassTypeStr(T&& t) { return str; }                                                                         \
template <typename T>                                                                                          \
static typename std::enable_if<std::is_same<T, class_type>::value, std::string>::type                          \
GetClassTypeStr() { return str; }

#endif  // _CODE_MACRO_H
